<?php

/***  Documentation

    Greqo Analytics Acceptance Test
    
    Revision: $Rev$
    Last Update: $Date: 2009-05-21 04:48:45 +0000 (Thu, 21 May 2009) $
    Author: Tom at klenwell@gmail.com
  
NOTES
    Requires user info to be configured in login file in conf dir

______________________________________________________________________________*/

$dn1 = dirname;
$ds = DIRECTORY_SEPARATOR;
$root_dir = $dn1($dn1($dn1(__FILE__))) . $ds;

// import classes to test
require_once($root_dir . 'greqo/analytics.class.php');


class AnalyticsAcceptanceTest {
    
    /*
        You should only need to add methods beginning test as in testSomething
        as in SimpleTest in modifying this class, though it gives you the
        opportunity for additional stuff.
    */
    
    var $debug = 0;
    var $Log_ = array();
    var $ResultLog = array();
    var $FailLog = array();
    
    function AnalyticsAcceptanceTest()
    {
        /* php4 constructor */
        $this->start_time = $this->utime();
        $this->Analytics = new GreqoAnalytics();
        
        // test user
        if ( !empty($this->Analytics->email) )
            $this->pass("user set to {$this->Analytics->email}");
        else
            $this->fail('Blogger user not set');
    }
    
    function run()
    {
        $this->log('starting test at ' . $this->start_time);
        $TestMethods = $this->_get_test_methods();
        foreach ( $TestMethods as $m ) $this->$m();
        $this->end_time = $this->nf($this->utime() - $this->start_time);
        print $this->reporter();        
    }


    /* TEST METHODS */  
    function testInstance() {
        $this->assert( is_a($this->Analytics, 'GreqoAnalytics'),
             'instance exists' );
    }
    
    function testLogin() {
        $this->assert( $this->Analytics->login(),
            "is logged in: {$this->Analytics->is_logged_in}" );
        $this->assert( count($this->Analytics->LoginCookies),
            count($this->Analytics->LoginCookies) . ' login cookies (listed below)' );
        $this->assert( $this->Analytics->GreqoResponse->code_class == 2,
            'response code is 2' );
        $this->log($this->print_r($this->Analytics->GreqoResponse));
        $this->log($this->print_r($this->Analytics->LoginCookies));
    }
    
    function testAccountList() {
        $AccountList = $this->Analytics->get_account_list();
        $this->assert(count($AccountList),
            print_r(array('Account List' => $AccountList),1));
        $this->account_id = $AccountList[array_rand($AccountList)];
        $this->AccountList = $AccountList;
    }
    
    function testProfileList() {
        $ProfileList = $this->Analytics->get_profile_list($this->account_id);
        $this->assert(count($ProfileList),
            print_r(array('Profile List' => $ProfileList),1));
        
        // make sure it's not returning same thing as AccountList
        $Accounts_ = array_values($this->AccountList);
        $Profiles_ = array_values($ProfileList);
        $this->assert($Accounts_[0] != $Profiles_[0], 'account/profile lists differ');
        
        $this->log($this->print_r($this->Analytics->GreqoResponse));
        $this->ProfileList = $ProfileList;
    }
    
    function testSummaryReport() {
        /*
            Pick 2 random profiles from profile list and get summary
            reports
        */
        $Choice = array_rand($this->ProfileList, 2);
        $profile1 = $this->ProfileList[$Choice[0]];
        $profile2 = $this->ProfileList[$Choice[1]];
        
        // profile 1
        $summary1 = $this->Analytics->get_summary_report($profile1);
        $this->assert(
            strpos($summary1, 'Greqo Analytics Summary') !== false,
            $summary1);
        
        // profile 2
        $summary2 = $this->Analytics->get_summary_report($profile2);
        $this->assert(
            strpos($summary2, 'Greqo Analytics Summary') !== false,
            $summary2);
    }


    /* HELPER METHODS */
    function see_log() {
        return sprintf('test failed -- see log in %s%s%s.log for details',
                        $root_dir, 'tmp/log/', date('Ymd'));
    }
    
    function assert($pass, $m='') {
        if ( $pass )
        {
            $this->FailLog[] = 0;
            $this->ResultLog[] = array(
                'pass',
                $m,
                date('Y-m-d H:i:s'),
                $this->caller(),
                $this->rsplit()
            );
        }
        else
        {
            $this->FailLog[] = 1;
            $this->ResultLog[] = array(
                'fail',
                $m,
                date('Y-m-d H:i:s'),
                $this->caller(),
                $this->rsplit()
            );
        }
    }
    
    function log($m) {
       $this->Log_[] = array(
            $m,
            date('Y-m-d H:i:s'),
            $this->caller(1),
            $this->lsplit()
        ); 
    }
    
    function pass($m='') {
        $this->FailLog[] = 0;
        $this->ResultLog[] = array(
            'pass',
            $m,
            date('Y-m-d H:i:s'),
            $this->caller(),
            $this->rsplit()
        );
        return 1;
    }
    
    function fail($m='') {
        $this->FailLog[] = 1;
        $this->ResultLog[] = array(
            'fail',
            $m,
            date('Y-m-d H:i:s'),
            $this->caller(),
            $this->rsplit()
        );
        return 0;
    }
    
    function caller($back=2) {
        /* return array with function and line number going 2 back -- assumes
           will be called by fail, pass, or log */
        $Trace = debug_backtrace();
        #$this->pr($Trace);
        $f = basename($Trace[$back]['file']);
        $l = $Trace[$back]['line'];
        $fx = $Trace[$back]['function'];
        return array($f, $l, $fx);
    }
    
    function utime()
    {
        $utime = microtime();
        return $this->nf(substr($utime,0,9) + substr($utime,-10));
    }
    
    function lsplit()
    {
        static $last;
        $now = $this->utime();
        $last = !empty($last) ? $last : $now;
        $split = $this->nf($now - $last);
        $last = $now;
        return $split;
    }
    
    function rsplit() 
    {
        static $last;
        $now = $this->utime();
        $last = !empty($last) ? $last : $now;
        $split = $this->nf($now - $last);
        $last = $now;
        return $split;
    }    
    
    function nf($float, $dec=4)
    {
        return (float) number_format($float, $dec, '.', '');
    }

    function kill($html, $message='dying')
    {
        $this->print_d(htmlspecialchars($html), '#600');
        print $html;
        die($message);
    }
    
    function echo_d($message, $color='#ccc')
    {
        $_D = debug_backtrace();
        $f = basename($_D[0]['file']);
        $l = $_D[0]['line'];
        $loc = "{$f}:{$l}";
        $out = "<div style='line-height:1.5em; font-family:monospace; color:$color;'>$message <span style='color:#666;'>[$loc]</span></div>";
        $this->_DBG[] = "$loc -> " . strip_tags($message);
        echo $out;
        return;
    }
    
    function print_d($message, $color='#c33')
    {
        if ( $this->debug ) $this->echo_d($message, $color);
        return;
    }
    
    function print_r($Mixed)
    {
        $return = htmlspecialchars(print_r($Mixed, 1));
        $return = "<pre>$return</pre>";
        return $return;
    }
    
    function pr($Mixed, $header='')
    {
        if ( !empty($header) ) $header = "<b>$header</b>";
        $return = htmlspecialchars(print_r($Mixed, 1));
        $return = "<pre style='border:1px solid #ccc; background:#f3f3f3; padding:4px;'>$header\n\n$return</pre>";
        $this->echo_d($return, '#333');
    }
    
    function dump()
    {
        echo $this->print_r($this);
        return;
    }
    
    function _get_test_methods()
    {
        $TestMethodList = array();
        $MethodList = get_class_methods(__CLASS__);
        foreach ( $MethodList as $m )
        {   
            if ( substr($m,0,4) != 'test' ) continue;
            $TestMethodList[] = $m;
        }
        return $TestMethodList;
    }
    
    function reporter()
    {
        // log formatting
        $rlog_t = '<p class="%s"><b>%s</b> [%s] (%s) %s</p>';
        $log_t = '<p class="log">[%s (%s) &raquo; %s:%s] <b>%s</b></p>';
        
        // result log
        $result_log = '';
        foreach ($this->ResultLog as $Log) {
            $result_log .= sprintf($rlog_t, $Log[0], $Log[0], $Log[3][2], $Log[4], $Log[1]);
        }
        
        // log
        $log = '';
        foreach ($this->Log_ as $Log) {
            $log .= sprintf($log_t, $Log[1], $Log[3], $Log[2][0], $Log[2][1], $Log[0]);
        }
        
        // suite results
        $suite_result = ( array_sum($this->FailLog) > 0 ) ? 'fail' : 'pass';
        $suite_text = sprintf('passed %s of %s tests',
                              count(array_keys($this->FailLog, 0)),
                              count($this->FailLog));        
        
        // footer
        $footer = "script completed in {$this->end_time} s";        
        
        $html = <<<XHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<title>Klenwell Functional Test: %s</title>
<style>
body { font-family:arial,sans-serif; }
h2 { margin:0 0 8px; }
h3 { padding:4px; margin:0 0 12px; font-size:1.2em; border-width:2px 0; border-style:solid; }
.fail { background:#ffeeee; color:#660000; border-color:#ff0000; }
.pass { background:#eeffee; color:#006600; border-color:#00ff00; }
p { margin:0; }
pre .pass { margin:0; padding:3px; border-bottom:1px solid #00ff00; }
pre .pass b { color:#00ff00; }
pre .fail { margin:0; padding:3px; border-bottom:1px solid #ff0000; }
pre .fail b { color:#cc0000; }
.log { margin:0; padding:3px;
 background:#eee; border-bottom:1px solid #ccc; color:#666; 
}
h6.footer {
 margin:0; padding:4px; font-family:monospace; color:#36f;
 border:1px solid #36f; border-width:1px 0;
 font-weight:normal; background:#f3f6ff;
}
</style>
</head>
<body>
<h1>%s</h1>

<h3 class="%s">%s &raquo; %s</h3>

<h2>Tests</h2>
<pre>%s</pre>
<h2>Log</h2><pre>%s</pre>
<h6 class="footer">%s</h6>
</body>
</html>
XHTML;

        return sprintf($html, __CLASS__, __CLASS__,
                        $suite_result,
                        ucwords($suite_result),
                        $suite_text,
                        $result_log,
                        $log,
                        $footer);
    }
}


$Test = &new AnalyticsAcceptanceTest();
print $Test->run();
?>
